package com.example.getbook.controller;

import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.io.file.LineSeparator;
import com.alibaba.fastjson.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
//https://www.yqzww.co/
//https://www.qitxt.com
//
@Controller
@RequestMapping("/")
public class GetBookController {

    private ThreadLocal<Integer> numTheadLocal = new ThreadLocal<>();

    @Autowired
    RestTemplate restTemplate;
    @RequestMapping(value = "/getBook",method = RequestMethod.GET)
    public ModelAndView getBook(){
        ModelAndView view = new ModelAndView("getBook.html");

        return view;
    }

    @ResponseBody
    @RequestMapping(value = "/getBook",method = RequestMethod.POST)
    public JSONObject getBook(HttpServletRequest request,String downloadPath,String startUrl,Long sleepSec) throws IOException, InterruptedException {
        numTheadLocal.set(0);
        JSONObject json = new JSONObject();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");

        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(null, headers);
        String nextYeNum = "";
        String fileName = "xxx.txt";
        String paths[] = startUrl.split("/");
        String[] yeNums = paths[paths.length-1].split("\\.");
        try{
            if(yeNums.length ==2){
                nextYeNum = yeNums[0];
                fileName = paths[paths.length-2]+".txt";
                File file = new File(downloadPath+"/"+fileName);
                file.delete();
                file.createNewFile();
                String bookPath = startUrl.replace(paths[paths.length-1],"");

                boolean hasNext = true;
                while(hasNext){
                    JSONObject bookJson = readBook(httpEntity,bookPath,nextYeNum,sleepSec);
                    writeFile(file,bookJson);
                    if(bookJson.containsKey("nextYeNum")){
                        nextYeNum = bookJson.getString("nextYeNum");
                    }else{
                        hasNext = false;
                    }
                }
                json.put("code",200);
            }else{
                json.put("code",501);
            }

        }catch (Exception e){
            e.printStackTrace();
            json.put("code",500);
        }
        return json;
    }

    @ResponseBody
    @RequestMapping(value = "/getBook1")
    public JSONObject list(HttpServletRequest request) throws IOException, InterruptedException {

        JSONObject json = new JSONObject();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(null, headers);

        File file = new File("C:/Users/Administrator/Desktop/xxx.txt");
        file.delete();
        file.createNewFile();

        Long sleepSec = 2L;
        String nextYeNum = "19977558";
        boolean hasNext = true;
        while(hasNext){
            JSONObject bookJson = readBook(httpEntity,"https://www.qitxt.com/87/61987/",nextYeNum,sleepSec);
            writeFile(file,bookJson);
            if(bookJson.containsKey("nextYeNum")){
                nextYeNum = bookJson.getString("nextYeNum");
            }else{
                hasNext = false;
            }
        }
        return json;
    }

    private void writeFile(File file, JSONObject bookJson) {

        FileWriter fileWriter = FileWriter.create(file);
        String titleTemp = bookJson.getString("title");
        // 替换title 中的第n章 标题
        titleTemp = titleTemp.replaceAll("第[0-9]+章 ","");
        titleTemp = titleTemp.replaceAll("第[一二三四五六七八九十百千万零]+章 ","");
        Integer num = numTheadLocal.get();
        num++;
        numTheadLocal.set(num);
        String title = "第"+num+"章 " +titleTemp;
        int titleLength = title.length();
        if(titleLength > 15){
            title = title.substring(0,10);
        }
        fileWriter.append(title);
        fileWriter.append(LineSeparator.WINDOWS.getValue());
        if(titleLength > 15){
        fileWriter.append(bookJson.getString("title"));
        }
        fileWriter.append(bookJson.getString("content"));
        fileWriter.append(LineSeparator.WINDOWS.getValue());
        fileWriter.append(LineSeparator.WINDOWS.getValue());
    }

    public JSONObject readBook(HttpEntity<MultiValueMap<String, Object>> httpEntity,String bookPath,String yeNum,Long sleepSec) throws InterruptedException {
        JSONObject json = new JSONObject();
        ResponseEntity<String> response = null;
        while(response == null){
            try {
                response = restTemplate.exchange(
                        bookPath+yeNum+".html"
                        , HttpMethod.GET, httpEntity, String.class);
            }catch (Exception e){
                e.printStackTrace();
                Thread.sleep(10*1000L);
            }
        }

        String  html = response.getBody();
        if(sleepSec != null && sleepSec != 0){
            Thread.sleep(sleepSec*1000L);
        }else{
            Thread.sleep(600L);
        }
        //System.out.println(html);
        Document document = Jsoup.parse(html);

        String title = getTitle(document);
        String content = getContent(document);
        String nextYeNum = getNextYeNum(document);


        json.put("title",title);
        json.put("content",content);
        if(nextYeNum != null){
            json.put("nextYeNum",nextYeNum);
        }
        return json;
    }

    private String getNextYeNum(Document document) {

        Element element = document.getElementById("pb_next");
        String href = null;
        if(element != null){
            href = element.attr("href");
        }
        element = document.getElementById("link-next");
        if(element != null){
            href = element.attr("href");
        }
        element = document.getElementById("next_url");
        if(element != null){
            href = element.attr("href");
        }
        if(href == null){
            Elements elements = document.getElementsByClass("bottem2");
            if(elements!=null && elements.hasText()){
                elements = elements.get(0).getElementsByTag("a");
                for(int i = 0;i<elements.size();i++){
                    element = elements.get(i);
                    if(element.text().trim().equals("下一章") || element.text().trim().equalsIgnoreCase("next") || element.text().trim().equals("下一页") ){
                        href = element.attr("href");
                    }

                }

            }
        }
        if(href == null){
            Elements elements = document.getElementsByClass("m-page");
            if(elements!=null && elements.hasText()){
                elements = elements.get(0).getElementsByTag("a");
                for(int i = 0;i<elements.size();i++){
                    element = elements.get(i);
                    if(element.text().trim().equals("下一章") || element.text().trim().equalsIgnoreCase("next")){
                        href = element.attr("href");
                    }

                }

            }
        }
        if(href == null){
            Elements elements = document.getElementsByTag("body");
            if(elements!=null && elements.hasText()){
                elements = elements.get(0).getElementsByTag("a");
                for(int i = 0;i<elements.size();i++){
                    element = elements.get(i);
                    if(element.text().trim().equals("下一章") || element.text().trim().equalsIgnoreCase("next")){
                        href = element.attr("href");
                    }

                }

            }
        }

        if(href != null && href != ""){
            String paths[] = href.split("/");
            String[] yeNums = paths[paths.length-1].split("\\.");
            if(yeNums.length ==2){
                return yeNums[0];
            }else{
                return null;
            }
        }
        return null;
    }


    public String getTitle(Document document){
        Elements elements = document.getElementsByTag("h1");
        for (Element element : elements) {
            return element.text();
        }

        elements = document.getElementsByClass("view_t");
        if(elements!=null && elements.hasText()){
            return elements.get(0).text();
        }
        return null;
    }

    public String getContent(Document document){
        Element elements = document.getElementById("txt");
        if(elements ==null){
            elements = document.getElementById("booktxt");
        }
        if(elements ==null){
            elements = document.getElementById("content");
        }
        if(elements ==null){
            elements = document.getElementById("view_content_txt");
        }
        if(elements ==null){
            elements = document.getElementById("txtContent");
        }
        return elements.text();
    }

}
